/*
 * cgi.h
 *
 *  Created on: Sep 23, 2011
 *      Author: lindenb
 */

#ifndef CGI_H_
#define CGI_H_


#include <sstream>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
/**
 * name:
 * 	CGI
 *
 * author:
 *	Pierre Lindenbaum PhD. (2010)
 *	http://plindenbaum.blogspot.com
 *	plindenbaum@yahoo.fr
 */
class cgistreambuf:public std::streambuf
	{
	private:
		char buffer[BUFSIZ];
		bool printed;
		std::streambuf* delegate;
		std::map<std::string,std::string> header;

	public:
		cgistreambuf(std::streambuf* sb);
		void setStatus(int status);
		void setContentType(const char* s);
		virtual ~cgistreambuf();
		virtual int overflow(int c=EOF);
		virtual void flushHeaders();
		virtual bool headersFlushed();
	};


class CGI
	{
	public:
		/** simple parameter */
		class Param
			{
			private:
				std::string _key;
				std::string _value;
			public:
				Param(std::string key,std::string value);
				const char* name() const;
				const char* value() const;
				~Param();
			};

	protected:
		std::size_t max_input_size() const;
	private:
		std::vector<Param*> parameters;
		void parseGET();
		void parsePOST();
		void parseQueryString(std::istream& in,int maxCharRead);
		static int x2c(int c1,int c2);
		bool isMultipart();
	public:
		CGI();
		virtual ~CGI();
		const char* requestMethod() const;
		void parse();
		bool contains(std::string key) const;
		const char* getParameter(std::string key) const;
		std::set<std::string> getParameters(std::string key) const;
		std::set<std::string> getParameterNames() const;

	private:
		 void _var(std::ostream& out,const char* s);
	public:

		std::ostream& dump(std::ostream& out);
	};


#endif /* CGI_H_ */
